/*
JUN16.2021
DHT11驱动程序
*/
#define DHT11DAT 2
#define DHT11_STATUS_ERR 0X01//初始化错误返回值
#define DHT11_STATUS_NORM 0X00//正常运行
#define DHT11_STATUS_E_SUM 0X02//求和错误

char Coldat[40];//收集的数据
char tempData[9];
unsigned int humi;//湿度整型数据
unsigned int humiFloat;//湿度浮点数据
int temp;//温度整型数据
int tempFloat;//温度浮点数据
int sum;//校验和

void Rightshift()
{
  for(int i=0;i<8;i++)
  {
    tempData[i+1]=Coldat[i];
    }
  }

int init_dht11()//DHT11初始化
{
  pinMode(DHT11DAT,OUTPUT);//Arduino此时为主机模式，DHT11DAT为输出模式
  digitalWrite(DHT11DAT,HIGH);//拉高电平，持续100ms
  delay(100);
  digitalWrite(DHT11DAT,LOW);//拉低电平，持续25ms，以激活DHT11开始工作
  delay(25);
  digitalWrite(DHT11DAT,HIGH);
  delayMicroseconds(40);//发送一个持续40us的高电平脉冲，随后，DHT11DAT设置为INPUT模式，等待DHT11发送响应信号
  pinMode(DHT11DAT,INPUT);
  delayMicroseconds(5);
  while(digitalRead(DHT11DAT)==LOW)//若DHT11拉低电平，则DHT11初始化成功，并在60us后检测是否为高电平，若是，则DHT11正式开始传输数据
  {
    delayMicroseconds(70);
    if(digitalRead(DHT11DAT)==HIGH)
    {
      return DHT11_STATUS_NORM;
    }
  }
  while(digitalRead(DHT11DAT)==HIGH)
  {
    return DHT11_STATUS_ERR;
    }
  }
void RecDat()
{
  int startBeac;
  int endBeac;
  while(digitalRead(DHT11DAT)==HIGH)
  {
    delayMicroseconds(1);//若初始化后依旧为高电平，则继续待机等待
    }
    for(int i=0;i<40;i++)
    {
     while(digitalRead(DHT11DAT)==LOW)
     {
      delayMicroseconds(1);//低电平时等待高电平脉冲
       }
       if(digitalRead(DHT11DAT)==HIGH)
       {
        startBeac=micros();//获取当前arduino运行的时间，精确到us，该步骤仅执行一次
        while(digitalRead(DHT11DAT)==HIGH)
        {
          delayMicroseconds(1);
          }
        }
       endBeac=micros();//获取当前Arduino运行的时间，endBeac-startBeac就是高电平脉冲的长度
       if((endBeac-startBeac)>=35)//若高电平时间高于35us，判定为数据1
       {
         Coldat[i]=1;
        }
        else
        {
          Coldat[i]=0;//反之为0
          }
        
    }
    
  }

void CalcDat()
{
  Rightshift();
  humi=0;
  humiFloat=0;
  temp=0;
  tempFloat=0;
  for(int i=0;i<8;i++)
  {
    if(tempData[i]==1)
    {
    humi=humi|0x01;
    }
    else
    {
      }
      humi=humi<<1;      
    }
//分离湿度整型数据    
    for(int i=7;i<15;i++)
    {
    if(Coldat[i]==1)
    {
    humiFloat=humiFloat|0x01;
    }
    else
    {
      }
      humiFloat=humiFloat<<1;
      }
//分离湿度浮点数据          
    for(int i=15;i<23;i++)
    {
    if(Coldat[i]==1)
    {
    temp=temp|0x01;
    }
    else
    {
      }
      temp=temp<<1;
      }
//分离温度整型数据
    for(int i=23;i<31;i++)
    {
    if(Coldat[i]==1)
    {
    tempFloat=tempFloat|0x01;
    }
    else
    {
      }
      tempFloat=tempFloat<<1;
      }
//分离温度浮点数据        
  }
  
void setup() {
Serial.begin(9600);

}

void loop() {
if(init_dht11()==0)
{
  RecDat();
  for(int i=0;i<40;i++)
  {
  Serial.write(0x30+Coldat[i]);
  }  
  Serial.println();
  CalcDat();
  Serial.print(humi);
  Serial.print(" ");
  Serial.print(temp);
  Serial.println();
  }
  delay(1000);
}
